﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Mvc.XForms.Utilities {
	public static class ExpressionExtensions {
		/// <summary>
		/// Examines the lambda expression and returns the control ID. 
		/// </summary>
		/// <param name="exp">LINQ expression to parse</param>
		public static string ExtractID(this Expression exp) {
			var idExtractor = new ExpressionHelper();
			return idExtractor.ExtractID(exp);
		}

		public static Type ExtractType(this Expression exp) {
			if (exp.NodeType != ExpressionType.Convert)
				return exp.Type;
			else if (exp is UnaryExpression)
				return ExtractType(((UnaryExpression)exp).Operand);
			else
				throw new Exception("Extract type failed");
		}

		/// <summary>
		/// Examines the lambda expression and returns the first member name. 
		/// </summary>
		/// <param name="exp">LINQ expression to parse</param>
		public static string ExtractMember(this Expression exp) {
			MemberExpression memExp;
			if (exp is MemberExpression) {
				memExp = exp as MemberExpression;
			} else if (exp is UnaryExpression) {
				var unaryExp = exp as UnaryExpression;
				memExp = unaryExp.Operand as MemberExpression;
			} else if (exp is MethodCallExpression) {
				var methExp = exp as MethodCallExpression;
				memExp = methExp.Object as MemberExpression;
			} else if (exp is ParameterExpression) {
				return string.Empty;
			} else {
				throw new Exception(string.Format("Error extracting control ID from lambda expression \"{0}\": Expression must only contain members and list index accessors", exp));
			}

			return memExp.Member.Name;
		}
	}
}
